package com.cloudeasy.user.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.cloudeasy.api.util.ResultUtil;
import com.cloudeasy.api.vo.PageResult;
import com.cloudeasy.api.vo.user.AttentionVO;
import com.cloudeasy.api.vo.Result;
import com.cloudeasy.core.bean.JwtParser;
import com.cloudeasy.user.po.Attention;
import com.cloudeasy.user.po.UserInfo;
import com.cloudeasy.user.service.AttentionService;
import com.cloudeasy.user.service.UserInfoService;
import com.cloudeasy.user.util.AttentionUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@RestController
@CrossOrigin
public class AttentionController {

    private final AttentionService attentionService;

    private final UserInfoService userInfoService;

    private final JwtParser jwtParser;

    public AttentionController(AttentionService attentionService, UserInfoService userInfoService, JwtParser jwtParser) {
        this.attentionService = attentionService;
        this.userInfoService = userInfoService;
        this.jwtParser = jwtParser;
    }

    /**
     * 关注用户
     *
     * @param authentication {@link Authentication}
     * @param attentionId    关注的用户Id
     * @return {@link Result<Boolean>}
     */
    @PostMapping("/attention/{attentionId}")
    public Result<Boolean> attention(Authentication authentication, @PathVariable("attentionId") String attentionId) {
        String userId = (String) jwtParser.getOnBody(authentication, "userId");
        return ResultUtil.success(attentionService.attention(userId, attentionId));
    }

    /**
     * 取消关注用户
     *
     * @param authentication {@link Authentication}
     * @param attentionId    要取消关注的用户Id
     * @return {@link Result<Boolean>}
     */
    @DeleteMapping("/attention/{attentionId}")
    public Result<Boolean> removeAttention(Authentication authentication, @PathVariable("attentionId") String attentionId) {
        String userId = (String) jwtParser.getOnBody(authentication, "userId");
        return ResultUtil.success(attentionService.removeAttention(userId, attentionId));
    }

    /**
     * 查看关注的用户
     *
     * @param userId 用户Id
     * @return {@link List<AttentionVO>}的{@link Result}
     */
    @GetMapping("/attention/{userId}")
    public Result<List<AttentionVO>> attentionList(@PathVariable("userId") String userId) {
        List<Attention> attentions = attentionService.listByUserId(userId);
        return ResultUtil.success(AttentionUtil.convert(obtainUserInfo(attentions, Attention::getAttentionId)));
    }

    /**
     * 分页查看关注的用户
     *
     * @param userId 用户Id
     * @param page   页数
     * @param size   每页大小
     * @return {@link PageResult<AttentionVO>}的{@link Result}
     */
    @GetMapping("/attention/{userId}/{page}/{size}")
    public Result<PageResult<AttentionVO>> attentionPage(@PathVariable("userId") String userId,
                                                         @PathVariable("page") Integer page,
                                                         @PathVariable("size") Integer size) {
        IPage<Attention> attentions = attentionService.pageByUserId(userId, page, size);
        return ResultUtil.success(AttentionUtil.convert(attentions, obtainUserInfo(attentions.getRecords(), Attention::getAttentionId)));
    }

    /**
     * 查看用户的粉丝
     *
     * @param attentionId 被关注的用户Id
     * @return {@link List<AttentionVO>}的{@link Result}
     */
    @GetMapping("/fans/{attentionId}")
    public Result<List<AttentionVO>> fansList(@PathVariable("attentionId") String attentionId) {
        List<Attention> attentions = attentionService.listById(attentionId);
        return ResultUtil.success(AttentionUtil.convert(obtainUserInfo(attentions, Attention::getUserId)));
    }

    /**
     * 分页查看用户的粉丝
     *
     * @param attentionId 被关注的用户Id
     * @param page        页数
     * @param size        每页大小
     * @return {@link PageResult<AttentionVO>}的{@link Result}
     */
    @GetMapping("/fans/{attentionId}/{page}/{size}")
    public Result<PageResult<AttentionVO>> fansPage(@PathVariable("attentionId") String attentionId,
                                                    @PathVariable("page") Integer page,
                                                    @PathVariable("size") Integer size) {
        IPage<Attention> attentions = attentionService.pageById(attentionId, page, size);
        return ResultUtil.success(AttentionUtil.convert(attentions, obtainUserInfo(attentions.getRecords(), Attention::getUserId)));
    }

    /**
     * 获取用户信息列表
     *
     * @param attentions        {@link List<Attention>}
     * @param idsObtainFunction Id提取函数
     * @return {@link List<UserInfo>}
     */
    private List<UserInfo> obtainUserInfo(List<Attention> attentions, Function<Attention, String> idsObtainFunction) {
        List<UserInfo> userInfos = new ArrayList<>();
        List<String> userIds = attentions.stream().map(idsObtainFunction).collect(Collectors.toList());

        if (userIds.size() > 0) {
            userInfos.addAll(userInfoService.listByIds(userIds));
        }

        return userInfos;
    }
}
